#coding:utf-8


__author__ = 'aesop'

#微信公众平台接收被动响应的入口
from flask import Flask
from flask import request
from flask import abort
from functools import wraps
import hashlib
import config

#获取设置的token
__token = config.weixin_token


def index(app):
    @app.route('/', methods=['GET', 'POST'])
    #拦截器，如果不符合条件则返回500
    @valid_to_pass
    def response_wechat():
        if request.method == 'POST':
            #微信post的数据需用stream或者data处理
            input_stream = request.data
            return input_stream
        #如果不是POST方法，则返回nonce（也就是配置公众平台的时候需要）
        else:
            return request.args.get('nonce','')


#拦截器！写法很高级
def valid_to_pass(fn):
#下述这两行声明十分重要，大致作用是闭包，也可以说是作用域转移
    @wraps(fn)
    def __valid(*args, **kwargs):
        signature = request.args.get('signature')
        timestamp = request.args.get('timestamp')
        nonce = request.args.get('nonce')
        if(__check_signature(signature, timestamp, nonce)):
             return fn(*args, **kwargs)
        else:
            abort(500)

    return __valid


#用于检验消息有效性的函数
#字典序排序取哈希
def __check_signature(signature, timestamp, nonce):
    arg_list = [__token, timestamp, nonce]
    arg_list.sort()
    result = ""
    for item in arg_list:
        result += str(item)
    signature_expect = hashlib.sha1(result).hexdigest()
    if(signature_expect  == signature):
        return True
    else:
        return False


if __name__ == '__main__':
    app = Flask(__name__)
    index(app)
    app.run(debug = True)


